package hasthi.common;

import hasthi.common.constants.HasthiConstants;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class LogFile {
    private static Map<String,LogFile> logfileMap = new ConcurrentHashMap<String, LogFile>();
    
    public static void flushAll(){
        for(LogFile file:logfileMap.values()){
            file.flush();
        }
    }
    
    static{
        final Thread thread = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(30000);
                    flushAll();
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        });
        thread.setDaemon(true);
        thread.start();
    }
    private int writeCount = 0;
    
    public static LogFile getLog(String name){
        LogFile logFile = logfileMap.get(name);
        if(logFile == null){
            logFile = new LogFile(name);
            logfileMap.put(name, logFile);
        }
        return logFile;
    }
    
    private Writer out; 
    private String name;
    private LogFile(String name){
        try {
            this.name = name;
            String file = name +"_"+System.currentTimeMillis();
            String logDir = System.getProperty(HasthiConstants.LOG_DIR);
            logDir = (logDir == null)?System.getenv(HasthiConstants.LOG_DIR_ENV):logDir;
            if(logDir != null){
                file = logDir + "/" + file +".log";
            }else{
                file = File.createTempFile(file, ".log").getAbsolutePath();
            }
            out =  new BufferedWriter(new FileWriter(file,true));
            out.append("#### Hathi Log ("+Utils.getLocalHost()+")###\n");
            System.out.println("logfile "+ file + " created");
        } catch (IOException e) {
            out = null;
            e.printStackTrace();
        }
    }
    @Override
    protected void finalize() throws Throwable {
        out.close();
    }

    
    public synchronized void flush(){
        try {
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public synchronized void append(String str){
        try {
            out.write(str);
            writeCount++;
            if(writeCount == 5){
                out.flush();
                writeCount = 0;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public void close(){
        try {
            out.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
